import 'dart:async';
import 'dart:io';
import 'package:Smart/commons/file_cache/gs_file_cache_util.dart';
import 'package:Smart/utils/event_bus_util.dart';
import 'package:Smart/utils/string_util.dart';
import 'package:Smart/utils/toast_util.dart';
import 'package:dio/dio.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';

String downloadFinishKey = "kDownloadFinish";
String downloadAllFinishKey = "kDownloadAllFinish";

/// 下载文件（针对视频）
class GSFileDownload {
  factory GSFileDownload() => _getInstance();
  static GSFileDownload get instance => _getInstance();
  static GSFileDownload _instance;

  GSFileDownload._internal() {
    dio = Dio();
    cancelToken = CancelToken();
    downloadTastList = [];
  }

  static GSFileDownload _getInstance() {
    if (_instance == null) {
      _instance = new GSFileDownload._internal();
    }
    return _instance;
  }

  //--------------------//

  Dio dio; // 网络库
  CancelToken cancelToken; // 取消下载
  List<String> downloadTastList; // 下载列表
  String currentDownloadUrl; // 当前下载地址
  String cachePath; // 缓存目录

  // 初始化目录结构
  Future<String> initCachePath() async {
    cachePath = (await getApplicationDocumentsDirectory()).path;
    cachePath = cachePath + "/cache/videos";
    await checkExists(cachePath);
    return cachePath;
  }

  // 添加任务
  addTask(List<String> urls, {String savePath}) {
    if (cancelToken.isCancelled) {
      cancelToken = CancelToken();
    }

    if (urls == null) return;
    downloadTastList.addAll(urls);
    if (currentDownloadUrl == null) {
      run();
    }
  }

  // 取消所有下载
  cancelAllTask() {
    downloadTastList = [];
    currentDownloadUrl = null;
    cancelToken.cancel("cancelDownload");
  }

  // 取消某一个下载任务
  cancelTask(String url) {
    if (url == currentDownloadUrl) {
      cancelToken.cancel();
      downloadTastList.removeWhere((element) => element == url);
      run();
    } else {
      downloadTastList.removeWhere((element) => element == url);
    }
  }

  // 定时任务
  run() async {
    if (downloadTastList.isNotEmpty) {
      print("剩余${downloadTastList.length}个任务");
      currentDownloadUrl = downloadTastList.first;
      var uri = Uri.parse(currentDownloadUrl);
      // if (cachePath == null) {
      //   await initCachePath();
      // }
      // String savePath =
      //     "$cachePath/${StringUtil.md5Str(currentDownloadUrl)}.${uri.pathSegments.last.split(".").last}";
      // if (!StringUtil.isUrl(currentDownloadUrl) ||
      //     await File(savePath).exists()) {
      //   print("已经下载跳过");
      //   downloadTastList.removeAt(0);
      //   run();
      //   return;
      // }
      String videoCache = await GSFileCacheUtil.getVideosCache();
      String savePath = videoCache +
          "/" +
          StringUtil.md5Str(currentDownloadUrl) +
          "." +
          uri.pathSegments.last.split(".").last;
      if (await GSFileCacheUtil.checkFileExists(savePath)) {
        print("已经下载跳过");
        downloadTastList.removeAt(0);
        run();
        return;
      }
      print("开始下载");
      try {
        Dio()
            .download(currentDownloadUrl, savePath, cancelToken: cancelToken)
            .then((value) async {
          print("下载完成");
          downloadTastList.removeAt(0);
          run();
          await ImageGallerySaver.saveFile(savePath);
          // EventBus().emit("download", ArgumentError());
        });
      } catch (e) {
        print(e);
      }
    } else {
      print("已全部下载完成");
      currentDownloadUrl = null;
      EventBus().emit("download");
      Toast.showText("下载完成");
    }
  }

  // 是否已下载
  Future<String> checkDoanloaded(String url) async {
    // var uri = Uri.parse(url);
    // if (cachePath == null) {
    //   await initCachePath();
    // }
    // String savePath =
    //     "$cachePath/${StringUtil.md5Str(url)}.${uri.pathSegments.last.split(".").last}";
    String savePath = await GSFileCacheUtil.localPathWithUrl(url);
    if (await File(savePath).exists()) {
      return savePath;
    }
    return null;
  }

  // 判断目录是否存在，不存在创建目录
  Future<bool> checkExists(String path) async {
    var file = Directory(path);
    try {
      bool exists = await file.exists();
      if (!exists) {
        await file.create();
        print("创建缓存目录：$path");
        return await checkExists(path);
      } else {
        return true;
      }
    } catch (e) {
      print(e);
      return false;
    }
  }

  // 查询缓存目录文件
  Future<List<FileSystemEntity>> query({String path}) async {
    if (cachePath == null) {
      await initCachePath();
    }
    path = path ?? cachePath;
    Directory directory = new Directory(path);
    return directory.listSync();
  }
}
